<script setup lang="ts">
import { ElForm, UploadUserFile } from 'element-plus'
import YkUploadImage from '@yk/components/upload/upload-image/YkUploadImage.vue'
import { TabBarUtil } from '@/layout/components/tab-bar'
import { DeviceSaveForm } from '@/api/entity/device'
import { Gateway } from '@/api/entity/gateway'
import { getGatewayListAPI } from '@/api/gateway'
import { getSceneListAPI } from '@/api/scene'
import { required } from '@utils/form-rule'
import { ObjectUtil } from '@utils/object-util'
import { addDeviceAPI, checkDeviceNameRepeatAPI, editDeviceAPI, getDeviceByIdAPI } from '@/api/device'
import { getVariableModelListAPI } from '@/api/variable'
import { Template } from '@/api/entity/variable'
import { FileUtil, MountedCheck, toEditPageCheck } from '@/utils'
import { SceneDTO } from '@/api/entity/scene'
import { DeviceRoleUtil } from '@/dataset/device-role'
import DebuggerGateway from '@views/gateway/components/debugger-gateway/DebuggerGateway.vue'

const route = useRoute()
const router = useRouter()

// 添加编辑或查看
const pageType = route.name.toString()

const mc = new MountedCheck()
onMounted(() => {
  DeviceRoleUtil.updateRole()
  getGatewayList()
  getSceneList()
  getVariableModelList()
  if (['CheckDevice', 'EditDevice'].includes(pageType)) {
    getDeviceData()
  }
  mc.end()
})
onActivated(() => {
  if (mc.isMounted()) return
  DeviceRoleUtil.updateRole()
})

// region TODO 数据回显
// 备份
let _saveForm: DeviceSaveForm = null
function getDeviceData () {
  const loading = ElLoading.service()
  getDeviceByIdAPI({ id: route.query.id.toString() }).then((res) => {
    res.result().then((rdata) => {
      saveForm.value = new DeviceSaveForm(rdata.data)
      _saveForm = ObjectUtil.copy(saveForm.value)
    })
  }).finally(loading.close)
}
// endregion

// region TODO 表单
const saveForm = ref(new DeviceSaveForm())
const saveFormRules = {
  // 设备名称
  deviceName: [required('设备名称为必填项')],
  // 网关id
  gatewayId: [required.change('网关为必填项')],
  // 从机地址
  slaveAddress: [required('从机地址为必填项')],
  // 变量模版id
  templateId: [required.change('变量模版为必填项')]
}
const saveFormRef = shallowRef<InstanceType<typeof ElForm>>()
// 图片
const deviceImageFile = shallowRef<UploadUserFile>(null)
const defaultImageSrc = computed(() => FileUtil.prefixImage(saveForm.value.url))
function submitSaveForm () {
  saveFormRef.value.validate().then(async () => {
    // 校验设备名称是否相同
    if (await checkDeviceNameRepeat()) {
      try {
        await ElMessageBox.confirm('当前网关下已存在相同的设备名称，名称相同可能存在查找不便，是否继续？', '重复提醒')
      } catch (e) {
        return
      }
    }
    const loading = ElLoading.service()
    if (deviceImageFile.value?.raw) {
      loading.setText('正在上传图片...')
      const url = await FileUtil.updateFile(deviceImageFile.value.raw)
      if (url) saveForm.value.url = url
      else {
        loading.close()
        return
      }
    }
    loading.setText('正在保存...')
    const params = ObjectUtil.copy(saveForm.value)
    const result = saveForm.value.id ? editDeviceAPI(params) : addDeviceAPI(params)
    result.then((res) => {
      res.result().then(() => {
        ElMessage.success('保存成功')
        const name = route.name
        TabBarUtil.value.open({ name: 'DeviceManage' }).then(() => {
          TabBarUtil.value.close(name)
        })
      })
    }).finally(loading.close)
  })
}
// endregion

// region TODO 名称校验 true 重复
async function checkDeviceNameRepeat () {
  const { id, deviceName, gatewayId } = saveForm.value
  const res = await checkDeviceNameRepeatAPI({ id, deviceName, gatewayId })
  const rdata = await res.result()
  return rdata.data
}
// endregion

// region TODO 网关
const gatewayList = shallowRef<Gateway[]>([])
function getGatewayList () {
  getGatewayListAPI().then((res) => {
    res.result().then((rdata) => {
      gatewayList.value = rdata.data
    })
  })
}
// endregion

// region TODO 调试
const debuggerGatewayInfo = shallowRef<Gateway>()
function openDebugger () {
  debuggerGatewayInfo.value = gatewayList.value.find(item => item.id === saveForm.value.gatewayId)
}
// endregion

// region TODO 变量模板
const variableModelList = shallowRef<Template[]>([])
function getVariableModelList () {
  getVariableModelListAPI().then((res) => {
    res.result().then((rdata) => {
      variableModelList.value = rdata.data
    })
  })
}
function variableChangeHandle () {
  variableChangeTip()
}
// 变量模板变更提醒
const isVariableChangeTip = shallowRef(true)
function variableChangeTip () {
  if (_saveForm.templateId && route.name === 'EditDevice' &&
    isVariableChangeTip.value && saveForm.value.templateId !== _saveForm.templateId) {
    ElMessageBox.confirm('修改变量模板将删除使用此模板时产生的数据，请谨慎操作。是否修改？', '变量模板变更提醒', {
      type: 'error'
    }).then(() => {
      isVariableChangeTip.value = false
    }).catch(() => {
      saveForm.value.templateId = _saveForm.templateId
    })
  }
}
// endregion

// region TODO 场景
const sceneList = shallowRef<SceneDTO[]>([])
function getSceneList () {
  getSceneListAPI().then((res) => {
    res.result().then((rdata) => {
      sceneList.value = rdata.data
    })
  })
}
// endregion

// region TODO 路由跳转
function toBackNavigator () {
  router.back()
  setTimeout(() => {
    TabBarUtil.value.close(pageType)
  }, 160)
}
// 前往变量模板编辑设备
function toEditVariableTemplate (id: string) {
  toEditPageCheck({
    id,
    name: 'EditVariableTemplate',
    message: '已存在未编辑完成的表单',
    query: { id }
  })
}
// endregion

</script>

<template>
  <div class="layout_view d-flex" style="min-height: 100%;">
    <!--表单-->
    <div class="c_card-page flex-1">
      <el-form
        ref="saveFormRef"
        :rules="saveFormRules" :model="saveForm" class="c_form-save"
        :disabled="pageType === 'CheckDevice'"
        label-width="150px"
      >
        <template v-if="route.name === 'AddDevice' || DeviceRoleUtil.isAdmin(saveForm.id)">
          <!--关联网关-->
          <div class="form-group">
            <div class="c_card_header c_card-title bor-divider-b">关联网关</div>
            <el-form-item prop="gatewayId" label="关联网关：">
              <el-select v-model="saveForm.gatewayId" filterable placeholder="请选择关联网关">
                <el-option v-for="item in gatewayList" :key="item.id" :label="item.name" :value="item.id" />
              </el-select>
              <refresh-btn class="ml-2 fs-24 color-primary" @click="getGatewayList" />
              <el-button
                v-if="pageType !== 'CheckDevice'"
                type="primary" class="ml-2"
                plain @click="openDebugger"
              >
                调试
              </el-button>
            </el-form-item>
            <el-form-item prop="slaveAddress" label="从机ID：">
              <el-input v-model.trim="saveForm.slaveAddress" placeholder="请输入从机ID" />
            </el-form-item>
          </div>
          <!--变量数据-->
          <div class="form-group">
            <div class="c_card_header c_card-title bor-divider-b" style="margin-top: 60px;">变量数据</div>
            <el-form-item prop="templateId" label="变量模板：">
              <div class="d-flex-center">
                <el-select v-model="saveForm.templateId" filterable placeholder="请选择变量模板" @change="variableChangeHandle">
                  <el-option v-for="item in variableModelList" :key="item.id" :label="item.modelName" :value="item.id" />
                </el-select>
                <refresh-btn class="ml-2 fs-24 color-primary" @click="getVariableModelList" />
              </div>
              <p v-if="route.name === 'EditDevice'" class="c_form-tip">
                <span class="color-error mr-1">*</span>
                <span>修改变量模板将删除使用此模板时产生的数据，请谨慎操作</span>
              </p>
            </el-form-item>
          </div>
        </template>
        <!--设备配置-->
        <div class="form-group">
          <div class="c_card_header c_card-title bor-divider-b">设备配置</div>
          <el-form-item v-if="route.name === 'AddDevice' || DeviceRoleUtil.isManager(saveForm.id)" prop="deviceName" label="设备名称：">
            <el-input v-model.trim="saveForm.deviceName" :maxlength="20" show-word-limit placeholder="请输入设备名称" />
          </el-form-item>
          <el-form-item v-if="route.name !== 'AddDevice' && DeviceRoleUtil.isOnlyManager(saveForm.id)" label="变量模板：">
            <el-button type="primary" plain @click="toEditVariableTemplate(saveForm.templateId)">编辑变量模板</el-button>
          </el-form-item>
          <el-form-item prop="groupId" label="所属场景：">
            <el-select
              v-model="saveForm.groupIds" filterable multiple
              collapse-tags
              placeholder="请选择所属场景"
            >
              <el-option v-for="item in sceneList" :key="item.id" :label="item.name" :value="item.id" />
            </el-select>
            <refresh-btn class="ml-2 fs-24 color-primary" @click="getSceneList" />
          </el-form-item>
          <el-form-item prop="notes" label="备注：">
            <el-input v-model.trim="saveForm.notes" placeholder="请输入备注" />
          </el-form-item>
          <template v-if="route.name === 'AddDevice' || DeviceRoleUtil.isManager(saveForm.id)">
            <el-form-item label="设备图片：">
              <div>
                <yk-upload-image v-model="deviceImageFile" width="120px" height="120px">
                  <template v-if="defaultImageSrc" #default>
                    <el-image :src="defaultImageSrc" class="wh-100" fit="contain" />
                  </template>
                </yk-upload-image>
                <p class="c_form-tip">图片建议尺寸140*140</p>
              </div>
            </el-form-item>
          </template>
        </div>
        <!--提交-->
        <div v-if="pageType !== 'CheckDevice'" style="margin-top: 60px">
          <el-affix position="bottom">
            <div class="text-center c_affix-bg-white c_form__submit-btn">
              <el-button type="primary" plain @click="toBackNavigator">取消</el-button>
              <el-button type="primary" @click="submitSaveForm">确认</el-button>
            </div>
          </el-affix>
        </div>
      </el-form>
      <!--返回-->
      <div v-if="pageType === 'CheckDevice'" class="text-center">
        <el-button type="primary" plain @click="toBackNavigator">返回</el-button>
      </div>
    </div>
    <!--调试框-->
    <div v-if="route.name === 'AddDevice' || DeviceRoleUtil.isAdmin(saveForm.id)" class="c_card-page flex-1 ml-12 overflow-hidden d-flex flex-column">
      <div class="c_card_header c_card-title bor-divider-b">调试窗口</div>
      <div class="position-relative flex-1 mt-16">
        <debugger-gateway :id="debuggerGatewayInfo?.id" :name="debuggerGatewayInfo?.name" class="h-100" />
      </div>
    </div>
  </div>
</template>

<style scoped lang="scss">
// 表单组合
.form-group {
  .c_card_header {
    margin-bottom: 32px;
  }
  & + .form-group {
    margin-top: 60px;
  }
}

// 调试
.debugging {
  background-color: #0C0C0C;
  color: var(--el-color-success);
  //max-height: calc(100% - 45px);
  overflow: auto;
  padding: 18px 32px;
}
</style>
